package com.example.concurrentprogramming8016.blockingqueue;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author liyanhao
 * @Date 2023-02-27 17:11
 */
public class MyBlockQueue<T> {

    private int lenth;
    private Queue<T> queue;
    private ReentrantLock reentrantLock = new ReentrantLock();
    private Condition cusomerCondition = reentrantLock.newCondition();
    private Condition providerCondition = reentrantLock.newCondition();

    public MyBlockQueue(int lenth) {
        this.lenth = lenth;
        this.queue = new LinkedList<>();
    }

    public T comsumer() throws InterruptedException {
        ThreadLocal<Object> objectThreadLocal = new ThreadLocal<>();
        reentrantLock.lock();
        try {
            T poll = queue.poll();
            if (poll == null) {
                cusomerCondition.await();
            }else {
               providerCondition.signal();
               return poll;
            }
        }finally {
            reentrantLock.unlock();
        }
        return null;
    }

    public void provider(T t) throws InterruptedException {
        reentrantLock.lock();
        try {
            if(queue.size() == lenth){
                providerCondition.await();
            }
            queue.add(t);
            cusomerCondition.signal();

        }finally {
            reentrantLock.unlock();
        }
    }
}
